package com.yt.server;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.yt.server.api.IServiceCapableConnection;
import com.yt.server.api.IServerHandler;
import com.yt.server.api.comm.ISession;
import com.yt.server.common.core.BaseServer;
import com.yt.server.messaging.Packet;

/**
 * 服务器Handler
 */
public class ServerHandler extends IoHandlerAdapter implements IServerHandler,
		BaseServer, ApplicationContextAware {

	private ApplicationContext ctx = null;

	private static final int IDLE_TIME = 10;

	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		ISession coreSession = Context.getSessionManager().getSession(
				(String) session.getAttribute(ISession.SESSION_ID));
		if (coreSession == null)
			sessionCreated(session);
		if (message != null && message instanceof Packet) {
			Packet packet = (Packet) message;
			// 校验数据包完整性,暂未实现
			switch (packet.getType()) {
			case NOOP:
				break;
			case JOIN:
				break;
			case SERVICE:
				((IServiceCapableConnection) coreSession.getConnection())
						.handleRemotingPacket(packet);
				break;
			case EXIT:
				break;
			default:
				break;
			}
		}
	}

	/**
	 * 发送时候调用
	 */
	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		super.messageSent(session, message);
	}

	/**
	 * 关闭时候调用
	 */
	@Override
	public void sessionClosed(IoSession session) throws Exception {
		try {
			Context.getSessionManager().removeSession(
					(String) session.getAttribute(ISession.SESSION_ID));
			session.removeAttribute(ISession.SESSION_ID);
			session.removeAttribute(ISession.SESSION_KEY);
			session.removeAttribute(ISession.SESSION_HANDSHAKE);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 建立时候调用
	 */
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		try {
			session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDLE_TIME);
			ISession s = Context.getSessionManager().createSession(session);
			session.setAttribute(ISession.SESSION_ID, s.getSessionId());
			session.setAttribute(ISession.SESSION_KEY, s);
			session.setAttribute(ISession.SESSION_HANDSHAKE, new Object());// Session握手
																			// 暂时Object代替
			// sendSecurity(session);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 空闲时候调用
	 */
	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
	}

	/**
	 * 方法sessionOpened会在一个连接被打开时调用，它通常会在方法sessionCreated调用之后被调用。如果线程类型特殊配置过，
	 * 该方法会在其他的线程中被调用，而不一定是在I/O处理器线程中被调用
	 */
	@Override
	public void sessionOpened(IoSession session) throws Exception {
	}

	@Override
	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException {
		this.ctx = arg0;
	}

	private void sendSecurity(IoSession session) {
		String security = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
				+ "  <!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n"
				+ "  <cross-domain-policy>\n"
				+ "   <site-control permitted-cross-domain-policies=\"all\"/>\n"
				+ "   <allow-access-from domain=\"*\" to-ports=\"9000-12000\" />\n"
				+ "  </cross-domain-policy>\n";
		session.write(security);
	}
}